home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Grab Bag
/
Shareware Grab Bag.iso
/
001
/
pibcalc.arc
/
PIBCALC.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1985-03-09
|
25KB
|
428 lines
(*$V-,B-,C-,U-,R-,X-*)
(* PIBCALC - Interactive Programmable Calculator *)
(*--------------------------------------------------------------------------*)
(* PibCalc --- Programmable Calculator *)
(*--------------------------------------------------------------------------*)
(* *)
(* Author: Philip R. Burns *)
(* Date: March, 1985 *)
(* Version: 1.0 *)
(* Systems: For MS-DOS on IBM PCs and close compatibles only. *)
(* *)
(* Overview: PibCalc is an interactive desk calculator designed for use *)
(* especially by programmers. PibCalc tries to combine the *)
(* features from better pocket calculators with the expression *)
(* syntax of the common algorithmic programming languages. *)
(* *)
(* PibCalc offers the following features: *)
(* *)
(* Integer and Real Floating Point Arithmentic *)
(* Octal, Decimal, and Hexadecimal Bases. *)
(* The usual arithmetic operators. *)
(* Common mathematical functions. *)
(* User-defined variables. *)
(* User-defined functions. *)
(* *)
(* NEEDED PROGRAM FILES *)
(* -------------------- *)
(* *)
(* The library file PIBCALC.LBR contains all of the needed files: *)
(* *)
(* (1) Program source files *)
(* *)
(* PIBCALC.PAS (main program) *)
(* SCREENROU.PAS *)
(* DUPL.PAS *)
(* EDITHELP.PAS *)
(* EDITSTRI.PAS *)
(* INITCALC.PAS *)
(* ERRORS.PAS *)
(* MATHROUT.PAS *)
(* READLINE.PAS *)
(* DISPLAY.PAS *)
(* GETTOK.PAS *)
(* ARITH.PAS *)
(* EXPRESSI.PAS *)
(* SETGUYS.PAS *)
(* DOGUYS.PAS *)
(* *)
(* (2) Program documentation file (on-line help) *)
(* *)
(* PIBCALC.HLP --- the text for the online HELP file. *)
(* *)
(* Documentation *)
(* ------------- *)
(* *)
(* The file PIBCALC.HLP contains more complete documentation on the *)
(* use of the PibCalc features. You should read this file through *)
(* before using PibCalc for the first time. PIBCALC.HLP can also be *)
(* read during a PibCalc session by entering the HELP command. *)
(* *)
(* Compiling PibCalc *)
(* ----------------- *)
(* *)
(* File PIBCALC.PAS is the main program source file, and contains *)
(* include statements for the remaining source files. Hence, to *)
(* compile PibCalc, enter Turbo (preferably Turbo-87), declare *)
(* PIBCALC.PAS to be the M)ain file, request compilation to a .COM *)
(* file using O)ptions, and enter C)ompile. *)
(* *)
(* PibCalc uses REAL arithmetic extensively, so that it benefits *)
(* considerably from the performance enhancement available from the *)
(* 8087 math co-processor. If you have an 8087/80287 chip, you *)
(* should compile PibCalc with TURBO-87. Doing so will result in a *)
(* CONSIDERABLE improvement in performance and accuracy. *)
(* *)
(* Using PibCalc *)
(* ------------- *)
(* *)
(* Once you have a compiled version of PibCalc, running it is *)
(* quite straightforward: just type *)
(* *)
(* PIBCALC *)
(* *)
(* in response to the DOS prompt. *)
(* *)
(* To leave PibCalc, type *)
(* *)
(* EXIT *)
(* *)
(* when you get the PibCalc prompt. *)
(* *)
(* Online Help *)
(* ----------- *)
(* *)
(* If the file PIBCALC.HLP is located in the same directory as PIBCALC, *)
(* and you execute PibCalc in that directory, then you can request the *)
(* online help during execution of PibCalc by entering the HELP command. *)
(* If the file PIBCALC.HLP is not found, then no help will be displayed. *)
(* *)
(* The file PIBCALC.HLP also contains more details on the use of various *)
(* PibCalc features. You should read it at least once before using *)
(* PibCalc. *)
(* *)
(*--------------------------------------------------------------------------*)
(* *)
(* Possible Improvements *)
(* --------------------- *)
(* *)
(* (1) PibCalc would benefit from the addition of complex *)
(* arithmetic. *)
(* (2) Additional functions to evaluate special mathematical and *)
(* statistical distributions would be useful. *)
(* (3) A more comprehensive programming facility allowing for *)
(* saving up statements, flow of control, and conditional *)
(* branching would be nice. *)
(* (4) > 16 bit integer arithmetic. *)
(* (5) Better trigonometric functions. *)
(* *)
(* Any Volunteers????? *)
(* *)
(*--------------------------------------------------------------------------*)
(* *)
(* Glitches *)
(* -------- *)
(* *)
(* (1) Turbo version 2.0 only allows 16-bit integers. Hence, any *)
(* integer expression outside this range will result in bad *)
(* results. Hopefully a later version will implement 32-bit *)
(* integers as provided by the 8087. To allow for this, *)
(* the type LONG_INTEGER is used to refer to integer values. *)
(* With version 2.0 of Turbo, this is just the ordinary 16-bit *)
(* integers. If longer integers become available, change *)
(* the definition of LONG_INTEGER to refer to these longer *)
(* integers. *)
(* *)
(* (2) A large part of PibCalc was previously implemented in a *)
(* mainframe dialect of Pascal. This Pascal, like the standard, *)
(* allowed out-of-block GOTOs. Out-of-block GOTOs are VERY *)
(* useful for getting out layers of recursive descent when *)
(* parsing or executing a stack of operations. Regrettably, *)
(* Turbo Pascal does NOT allow out-of-block GOTOs, resulting in *)
(* a considerable amount of less-than-elegant code to check and *)
(* re-check if global error flags have been set. *)
(* *)
(*--------------------------------------------------------------------------*)
(* *)
(* Credits: *)
(* -------- *)
(* *)
(* PibCalc is based in part on John Norstad's DCALC, in part on a *)
(* previous mainframe calculator program I wrote, and in part on a *)
(* number of other similar calculator programs. *)
(* *)
(* The WordStar-like string editing routine (for editing the last *)
(* command line or a function definition) is modified from a routine *)
(* I found on a BBS. My thanks to the anonymous author of the *)
(* original. *)
(* *)
(*--------------------------------------------------------------------------*)
(* *)
(* Where to send fan mail and letter bombs: *)
(* ---------------------------------------- *)
(* *)
(* Suggestions for improvements or corrections are welcome. *)
(* Please leave messages on Gene Plantz's BBS (312) 882 4227 *)
(* or Ron Fox's BBS (312) 940 6496. *)
(* *)
(* I hope that you find this program useful -- and, if you expand *)
(* please upload your extensions so that all of us can enjoy them! *)
(* *)
(*--------------------------------------------------------------------------*)
(*--------------------------------------------------------------------------*)
(* Global Constants *)
(*--------------------------------------------------------------------------*)
CONST
MaxLint = 32767 (* Maximum value of long integer *);
Maxstrlen = 255 (* Maximum string length *);
Maxstdfuncs = 25 (* Number of built-in functions *);
Maxuserfuncs = 20 (* Maximum number of user functions *);
Maxformal = 10 (* Maximum number of formal parameters *);
Maxtoknams = 18 (* Maximum number of syntactic tokens *);
(* Base of the Naperian Logarithms *)
EE = 2.718281828459045;
(* Guess what? *)
PI = 3.141592653589793;
col = 'a' (* End of string marker *) ;
cr = #13 (* Carriage return character *);
bs = #08 (* Backspace character *);
Ctrlx = ^x (* Line delete character *);
Ctrld = ^d (* Move right character *);
Ctrls = ^s (* Move left character *);
Ctrlh = ^h (* Alternate move left character *);
Ctrlf = ^f (* Move to end of line character *);
Ctrla = ^a (* Move to front of line character *);
Ctrlv = ^v (* Toggle insert/delete mode *);
(*--------------------------------------------------------------------------*)
(* Global Types *)
(*--------------------------------------------------------------------------*)
TYPE
(* Command names/user funcs/constants *)
Alfa = PACKED ARRAY[1..10] OF CHAR;
(* General string *)
AnyStr = STRING[Maxstrlen];
(* Change to long integer type if poss. *)
Long_Integer = INTEGER;
(* Command type *)
tokenty = ( exitsy, helpsy, decsy, octsy, hexsy,
fracsy, radsy, degsy, defsy, delsy,
showsy, varssy, funcssy, modsy, divsy,
varsy, constsy, eolsy, stdfuncsy, userfuncsy,
plussy, minussy, starsy, slashsy, exponsy,
oparsy, cparsy, equalssy, commasy, dollarsy,
periodsy, editsy );
(* Variable names are 'A' through 'Z' *)
varnamty = 'A'..'Z';
(* Types of values are integer and real *)
varty = ( int, rea );
(* Defined value type *)
valuety = RECORD
def: BOOLEAN (* If value assigned yet *);
typ: varty (* Which value applies -- integer or real *);
i: Long_Integer (* Integer value *);
r: REAL (* Real value *);
END;
(* Bases for arithmetic *)
basety = ( dec, oct, hex );
charsetty = SET OF CHAR;
(* Built-in functions/constants *)
stdfuncty = ( absf, minf, maxf, truncf, roundf,
sinf, cosf, tanf, cotf, secf,
cscf, asinf, acosf, atanf, acotf,
asecf, acscf, atan2f, expf, lnf,
log10f, logf, sqrtf, EEf, PIf );
(* Formal parameters for user function *)
formalty = RECORD
nump: INTEGER (* Number of formal parameters *);
parms: ARRAY [1..maxformal] OF
RECORD
name: varnamty (* Name of formal parameter *);
VAL: valuety (* Value type of formal par. *);
END
END;
(* Angle calcs -- degrees or radians *)
anglety = ( rad, deg );
(*--------------------------------------------------------------------------*)
(* Global Variables *)
(*--------------------------------------------------------------------------*)
VAR
UseEdit: BOOLEAN (* TRUE to use edited line *);
ErrorFlag: BOOLEAN (* Execution time error flag *);
HelpFile: TEXT (* File containing help text *);
Iline: AnyStr (* Command input line *);
Oline: AnyStr (* Saved command input line *);
Ipos: INTEGER (* Current position in command line *);
token: tokenty (* Current token from command line *);
varnam: varnamty (* Variable name if token = varsy *);
constval: valuety (* Constant value if token = constsy *);
istdfunc: INTEGER (* Index into Stdfuncs table if token *)
(* = Stdfuncsy *);
iuserfunc: INTEGER (* Index in userfuncs table if token *)
(* = Userfuncsy *);
curval: valuety (* Current accumulator value *);
(* Current variable values *)
VarVals: ARRAY[varnamty] OF valuety;
done: BOOLEAN (* TRUE when time to quit PibCalc *);
base: basety (* Current default base *);
Frac: INTEGER (* No. of digits to display after *)
(* decimal point. *);
angle: anglety (* Current angle units -- rad or deg *);
dummy: formalty (* Dummy (Empty) formal param. list *);
(* Standard Functions *)
stdfuncs: ARRAY[ 1 .. Maxstdfuncs ] OF
RECORD
name: alfa (* Function name *);
nparms: INTEGER (* No. of formal parameters *);
func: stdfuncty (* Type of built-in function *);
END;
(* User-defined functions *)
userfuncs: ARRAY[ 1 .. Maxuserfuncs ] OF
RECORD
name: alfa (* Function name *);
nparms: INTEGER (* No. of formal parameters *);
(* Parameter names *)
pnames: PACKED ARRAY [1..maxformal] OF varnamty;
defn: AnyStr (* Function definition text *);
END;
(* Commands/constants/func names *)
toknams: ARRAY[ 1 .. Maxtoknams ] OF
RECORD
name: alfa (* Token name *);
tok: tokenty (* Token type *);
END;
(*-----------------------------------------------------------------------*)
(* Global Color Variables *)
(*-----------------------------------------------------------------------*)
VAR
ForeGround_Color : INTEGER (* Color for ordinary text *);
BackGround_Color : INTEGER (* Usual background color *);
Help_Text_Color : INTEGER (* Help text color *);
Help_Header_Color : INTEGER (* Help header color *);
Prompt_Color : INTEGER (* Color for prompts *);
Error_Message_Color : INTEGER (* Color for error messages *);
(*-----------------------------------------------------------------------*)
(* Screen Types *)
(*-----------------------------------------------------------------------*)
CONST
Color_Screen_Address = $B800; (* Address of color screen *)
Mono_Screen_Address = $B000; (* Address of mono screen *)
Screen_Length = 4000; (* 80 x 25 x 2 = screen area length *)
TYPE
(* A screen image *)
Screen_Type = Array[ 1 .. Screen_Length ] Of BYTE;
Screen_Ptr = ^Screen_Image_Type;
Screen_Image_Type = RECORD
Screen_Image: Screen_Type;
END;
(*--------------------------------------------------------------------------*)
(* Screen Variables *)
(*--------------------------------------------------------------------------*)
VAR
(* Memory-mapped screen area *)
Actual_Screen : Screen_Ptr;
(*--------------------------------------------------------------------------*)
(* Included Routines *)
(*--------------------------------------------------------------------------*)
PROCEDURE NextTok;
FORWARD;
(*$I SCREENROU.PAS *)
(*$I DUPL.PAS *)
(*$I EDITHELP.PAS *)
(*$I EDITSTRI.PAS *)
(*$I INITCALC.PAS *)
(*$I ERRORS.PAS *)
(*$I MATHROUT.PAS *)
(*$I READLINE.PAS *)
(*$I DISPLAY.PAS *)
(*$I GETTOK.PAS *)
(*$I ARITH.PAS *)
(*$I EXPRESSI.PAS *)
(*$I SETGUYS.PAS *)
(*$I DOGUYS.PAS *)
(* ----------------------------------------------------------------- *)
BEGIN (* PibCalc -- Main Program *)
(* Initialize PibCalc execution *)
Initialize;
(* Display welcome *)
WRITELN('PibCalc version 1.0 ready. Type HELP for instructions.');
(* Loop over command lines *)
REPEAT
(* No errors found this line *)
Errorflag := FALSE;
(* Read command line *)
ReadLine;
(* Pick up first token on line *)
NextTok;
(* And execute appropriate task *)
IF ( NOT ErrorFlag ) THEN
CASE token OF
exitsy: DoExit;
helpsy: DoHelp;
decsy: SetBase ( dec );
octsy: SetBase ( oct );
hexsy: SetBase ( hex );
radsy: SetAngle( rad );
degsy: SetAngle( deg );
fracsy: SetFrac;
showsy: DoShow;
defsy: DoDef;
delsy: DoDel;
dollarsy: DoEsp;
eolsy: Display(' ',Curval);
editsy: DoEdit;
ELSE
DoExp;
END (* Case *);
UNTIL done;
END (* PibCalc *).